#pragma once

namespace AVUI {

/// <summary> Data structure used to describe the size of a three-dimensional object. </summary>
class Size3D
{
public:
    DECLARE_VALUE_ELEMENT(Size3D);

#pragma region Public Methods

    /// <summary> Initializes a new instance of the <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure. </summary>
    Size3D() : m_x(0.0f), m_y(0.0f), m_z(0.0f) { }

    /// <summary> Initializes a new instance of the <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure. </summary>
    /// <param name="x">The new <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure's <see cref="P:System.Windows.Media.Media3D.Size3D.X" /> value.</param>
    /// <param name="y">The new <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure's <see cref="P:System.Windows.Media.Media3D.Size3D.Y" /> value.</param>
    /// <param name="z">The new <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure's <see cref="P:System.Windows.Media.Media3D.Size3D.Z" /> value.</param>
    Size3D(float x, float y, float z);


    /// <summary> Compares two <see cref="T:System.Windows.Media.Media3D.Size3D" /> structures for equality.   Two <see cref="T:System.Windows.Media.Media3D.Size3D" /> structures are equal if the values of their <see cref="P:System.Windows.Media.Media3D.Size3D.X" />, <see cref="P:System.Windows.Media.Media3D.Size3D.Y" />, and <see cref="P:System.Windows.Media.Media3D.Size3D.Z" /> properties are the same.       Note: Because the value of Doubles can lose precision when arithmetic operations are performed on them, a comparison between two Doubles that are logically equal might fail.     </summary>
    /// <returns>true if the <see cref="P:System.Windows.Media.Media3D.Size3D.X" />, <see cref="P:System.Windows.Media.Media3D.Size3D.Y" />, and <see cref="P:System.Windows.Media.Media3D.Size3D.Z" /> components of <paramref name="size1" /> and <paramref name="size2" /> are equal; otherwise, false.</returns>
    /// <param name="rhs">The <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure to compare.</param>
    bool operator==(const Size3D& rhs) const { return m_x == rhs.m_x && m_y == rhs.m_y && m_z == rhs.m_z;  }

    /// <summary> Compares two <see cref="T:System.Windows.Media.Media3D.Size3D" /> structures for inequality.  Two <see cref="T:System.Windows.Media.Media3D.Size3D" /> structures are not equal if the values of their <see cref="P:System.Windows.Media.Media3D.Size3D.X" />, <see cref="P:System.Windows.Media.Media3D.Size3D.Y" /> and <see cref="P:System.Windows.Media.Media3D.Size3D.Z" /> properties are different.     Note: Because the value of Doubles can lose precision when arithmetic operations are performed on them, a comparison between two Doubles that are logically equal might fail.     </summary>
    /// <returns>true if the <see cref="P:System.Windows.Media.Media3D.Size3D.X" />, <see cref="P:System.Windows.Media.Media3D.Size3D.Y" /> and <see cref="P:System.Windows.Media.Media3D.Size3D.Z" /> coordinates of <paramref name="size1" /> and <paramref name="size2" /> are different; otherwise, false.</returns>
    /// <param name="rhs">The <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure to compare.</param>
    bool operator!=(const Size3D& rhs) const { return !(*this == rhs); }

#pragma endregion Public Methods

#pragma region Public Properties

    /// <summary> Gets a value that represents an empty <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure. </summary>
    /// <returns>An empty instance of a <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure.</returns>
    static Size3D get_Empty();

    /// <summary> Gets a value that indicates whether this <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure is empty. </summary>
    /// <returns>true if the <see cref="T:System.Windows.Media.Media3D.Size3D" /> structure is empty; otherwise, false.  The default is false.</returns>
    bool get_IsEmpty() const;

    /// <summary>Gets or sets the value of the X coordinate of the rectangle. </summary>
    /// <returns>Value of the X coordinate of the rectangle.</returns>
    float get_X() const { return m_x; }
    void set_X(float value);
    IMPLEMENT_VALUE_PROPERTY(X, float, false);

    /// <summary>Gets or sets the value of the Y coordinate of the rectangle. </summary>
    /// <returns>Value of the Y coordinate of the rectangle.</returns>
    float get_Y() const { return m_y; }
    void set_Y(float value);
    IMPLEMENT_VALUE_PROPERTY(Y, float, false);

    /// <summary>Gets or sets the value of the Z coordinate of the rectangle. </summary>
    /// <returns>Value of the Z coordinate of the rectangle.</returns>
    float get_Z() const { return m_z; }
    void set_Z(float value);
    IMPLEMENT_VALUE_PROPERTY(Z, float, false);

#pragma endregion Public Properties

private:

#pragma region Private Methods

    static Size3D CreateEmptySize3D();

#pragma endregion Private Methods
 
#pragma region Private Fields

    float m_x;
    float m_y;
    float m_z;

#pragma endregion Private Fields

};


};
